<?php
use frontend\modules\yii2\widgets\layouts\markdown\Markdown;
use frontend\modules\yii2\widgets\layouts\example\Example;
use yii\bootstrap\Button;
use yii\bootstrap\Alert;

$this->title = 'Yii2框架的源码安装教程及注意事项';
$this->registerMetaTag([
    'name' => 'keywords',
    'content' => 'yii,git,source,Yii2,install,源码,安装,教程'
]);
$this->registerMetaTag([
    'name' => 'description',
    'content' => '介绍如何以源码的方式安装Yii框架的运行环境'
]);
$this->registerMetaTag([
    'name' => 'author',
    'content' => 'chenzhiwei'
]);

$html = [
    "markdown0" => <<<M0
# 源码安装Yii框架
如果想以源码的方式安装Yii，那你首先需要安装正确版本的php，源码安装根据下载源码的方式不同，分为如下两种方法：
- composer安装法
- 归档文件安装法  

上述两种方法除了下载源码方式不一样，其他的都一样，但是特别注意你本地的php版本必须要满足Yii的要求，虽然Yii的`composer.json`文件中指定的php版本一直都是`"php": ">=5.6.0",`，但是其依赖所需要的php版本已经到了php7，所以如果你本地安装的php版本不够新，很大可能无法使用最新版本的yii。

## 安装PHP
为了方便起见，我在ubuntu系统中用[LAMP](https://lnmp.org/download.html)安装PHP，为了确保Yii能正确运行，我们选择LNMP能提供的最新的php版本：
```ruby
root@b429cc263c88:/tmp# uname -a
Linux b429cc263c88 5.10.29-amd64-desktop #2 SMP Mon Apr 26 09:48:13 CST 2021 x86_64 x86_64 x86_64 GNU/Linux
root@b429cc263c88:/tmp# apt-get install -y wget
root@b429cc263c88:/tmp# wget http://soft.vpser.net/lnmp/lnmp1.8.tar.gz
root@b429cc263c88:/tmp# tar -zxf lnmp1.8.tar.gz 
root@b429cc263c88:/tmp# cd lnmp1.8
root@b429cc263c88:/tmp# ./install.sh lnmp
+------------------------------------------------------------------------+
|          LNMP V1.8 for Ubuntu Linux Server, Written by Licess          |
+------------------------------------------------------------------------+
|        A tool to auto-compile & install LNMP/LNMPA/LAMP on Linux       |
+------------------------------------------------------------------------+
|           For more information please visit https://lnmp.org           |
+------------------------------------------------------------------------+
You have 11 options for your DataBase install.
1: Install MySQL 5.1.73
2: Install MySQL 5.5.62 (Default)
3: Install MySQL 5.6.51
4: Install MySQL 5.7.34
5: Install MySQL 8.0.25
6: Install MariaDB 5.5.68
7: Install MariaDB 10.1.48
8: Install MariaDB 10.2.38
9: Install MariaDB 10.3.29
10: Install MariaDB 10.4.19
0: DO NOT Install MySQL/MariaDB
Enter your choice (1, 2, 3, 4, 5, 6, 7, 8, 9, 10 or 0): 0
Do not install MySQL/MariaDB!
===========================
You have 9 options for your PHP install.
1: Install PHP 5.2.17
2: Install PHP 5.3.29
3: Install PHP 5.4.45
4: Install PHP 5.5.38
5: Install PHP 5.6.40 (Default)
6: Install PHP 7.0.33
7: Install PHP 7.1.33
8: Install PHP 7.2.34
9: Install PHP 7.3.29
10: Install PHP 7.4.21
11: Install PHP 8.0.8
Enter your choice (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11): 11
You will install PHP 8.0.8
===========================
You have 3 options for your Memory Allocator install.
1: Don't install Memory Allocator. (Default)
2: Install Jemalloc
3: Install TCMalloc
Enter your choice (1, 2 or 3): 1
You will install not install Memory Allocator.

Press any key to install...or Press Ctrl+c to cancel
... ...
root@b429cc263c88:/tmp/lnmp1.8# lnmp status
+-------------------------------------------+
|    Manager for LNMP, Written by Licess    |
+-------------------------------------------+
|              https://lnmp.org             |
+-------------------------------------------+
nginx (pid 23819) is running...
php-fpm is runing!
```

## Composer安装Yii框架
首先下载Composer:
```
root@b429cc263c88:/tmp/lnmp1.8# cd /home/wwwroot/
root@b429cc263c88:/home/wwwroot# curl -sS https://getcomposer.org/installer | php
All settings correct for using Composer
Downloading...

Composer (version 2.1.11) successfully installed to: /tmp/composer.phar
Use it: php composer.phar
```
**yii2-app-basic基础版**
```
php composer.phar create-project --prefer-dist yiisoft/yii2-app-basic basic
```
**yii2-app-advanced高级版**
```
php composer.phar create-project --prefer-dist yiisoft/yii2-app-advanced advanced
```

## 下载归档文件安装
如果你本地安装了Git，那可以直接从git仓库中拉取代码，我分享了两个仓库源：
- Yii官方在Github的仓库：[yii2-app-avanced](https://github.com/yiisoft/yii2-app-advanced.git)；
- 由于Yii官方没有在国内建立仓库，而国内访问国外网站Github又比较慢，因此我在国内的Gitee平台上同步了Github仓库：[yii2-app-avanced](https://gitee.com/lvzmen_github/yii2-app-advanced.git)；

因此如果通过git下载代码的话，可以如下两种方式：  

**通过Github下载：**
```
git clone -b 2.0.43 https://github.com/yiisoft/yii2-app-advanced.git advanced
```
**通过Gitee下载（国内较快）：**
```
git clone -b 2.0.43 https://gitee.com/lvzmen_github/yii2-app-advanced.git advanced
```

如果你没有安装git，那只有通过下载链接的方式安装了，[点我前往下载页面](https://www.yiiframework.com/download)，命令行方式下载：
```
wget https://github.com/yiisoft/yii2/releases/download/2.0.43/yii-advanced-app-2.0.43.tgz
```

### 安装依赖
下载的归档文件是没有vendor文件夹的，这个文件夹里是运行YII当前版本需要的各种依赖，需要通过composer来安装：
```
root@b429cc263c88:/home/wwwroot# git clone -b 2.0.43 https://gitee.com/lvzmen_github/yii2-app-advanced.git advanced-git
root@b429cc263c88:/home/wwwroot# cd advanced-git/
root@b429cc263c88:/home/wwwroot/advanced-git# curl -sS https://getcomposer.org/installer | php
root@b429cc263c88:/home/wwwroot/advanced-git# php composer.phar update
```

## 初始化Yii框架
无论是通过上述哪种方式下载的源码，都需要进行YII的初始化，因为缺少入口文件`index.php`和测试/生产环境下的配置文件`main.php`，初始化命令如下：
```
root@b429cc263c88:/home/wwwroot/advanced-git# ./init
Yii Application Initialization Tool v1.0

Which environment do you want the application to be initialized in?

  [0] Development
  [1] Production

  Your choice [0-1, or "q" to quit] 0

  Initialize the application under 'Development' environment? [yes|no] yes

  Start initialization ...

   generate yii_test.bat
   generate frontend/web/robots.txt
   generate frontend/web/index-test.php
   generate frontend/web/index.php
   generate frontend/config/params-local.php
   generate frontend/config/codeception-local.php
   generate frontend/config/main-local.php
   generate frontend/config/test-local.php
   generate backend/web/robots.txt
   generate backend/web/index-test.php
   generate backend/web/index.php
   generate backend/config/params-local.php
   generate backend/config/codeception-local.php
   generate backend/config/main-local.php
   generate backend/config/test-local.php
   generate yii_test
   generate console/config/params-local.php
   generate console/config/main-local.php
   generate console/config/test-local.php
   generate yii
   generate common/config/params-local.php
   generate common/config/codeception-local.php
   generate common/config/main-local.php
   generate common/config/test-local.php
   generate cookie validation key in backend/config/main-local.php
   generate cookie validation key in common/config/codeception-local.php
   generate cookie validation key in frontend/config/main-local.php
      chmod 0777 backend/runtime
      chmod 0777 backend/web/assets
      chmod 0777 console/runtime
      chmod 0777 frontend/runtime
      chmod 0777 frontend/web/assets
      chmod 0755 yii
      chmod 0755 yii_test

  ... initialization completed.

```

## Nginx配置
YII代码是配置完了，接下来就该配置nginx了，lnmp的`fastcgi.conf`文件不支持yii，因此需要修改一下配置：
```
sed -i 's/\$document_root\/\:\/tmp\/\:\/proc\//NULL/g' /usr/local/nginx/conf/fastcgi.conf
```

在lnmp中可以使用的nginx配置如下`/usr/local/nginx/conf/vhost/yii.conf`：
```
server {
    charset utf-8;
    client_max_body_size 128M;

    listen 8080; ## listen for ipv4
    #listen [::]:80 default_server ipv6only=on; ## listen for ipv6

    server_name 172.17.0.2;
    root        /home/wwwroot/advanced-git/frontend/web;
    index       index.php;

    access_log  /home/wwwlogs/yii_access.log;
    error_log   /home/wwwlogs/yii_error.log;

    #remove the index.php in url
    location / {
        # Redirect everything that isn't a real file to index.php
        try_files \$uri \$uri/ /index.php\$is_args\$args;
    }

    #send the request to php
    location ~ \.php$ {
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME \$document_root\$fastcgi_script_name;
        #fastcgi_pass 127.0.0.1:9000;
        fastcgi_pass unix:/tmp/php-cgi.sock;
        try_files \$uri =404;
    }

    access_log  /home/wwwlogs/yii_access.log;
    error_log   /home/wwwlogs/yii_error.log;
}
```
重启nginx后就可以正常访问了：
```
nginx -s reload
```
![Yii欢迎页面](/images/20211109180257.png)

### 格式化日志
默认的nginx日志格式如下：
```
172.17.0.1 - - [10/Nov/2021:14:11:56 +0800] "GET /site/about HTTP/1.1" 200 1109 "http://172.17.0.2:8080/site/contact" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36"
```
为了便于分析nginx的日志，我们通常会把nginx的日志设置为`json`格式，并添加另外一些重要的参数，如：post数据，效果如下：
```
{"ip":"172.17.0.1","time":"2021-11-10T14:45:55+08:00","host":"172.17.0.2:8080","request":"GET /site/index HTTP/1.1","status":"200","post":"","body_bytes_sent":"1441","req_time":"0.033","referer":"http://172.17.0.2:8080/site/about","ssl_client_s_dn":"","ssl_client_v_end":""}
```

## URL美化(pathinfo模式) id=pretty-url
上述配置当然没问题，但是有一点不足就是url并非pathinfo模式，上述页面的url为：
```
http://172.17.0.2:8080/index.php?r=site%2Findex
```
而更令人舒服的格式为：
```
http://172.17.0.2:8080/site/index
```
那怎么做呢？开启Yii的URL美化即可：
```
vim /home/wwwroot/advanced-git/frontend/config/main.php
... ...
return [
    ... ...
    'components' => [
        ......
        'urlManager' => [
            'enablePrettyUrl' => true,
            'showScriptName' => false,
            'rules' => [
            ],
        ],
    ],
    ......
];
......
```
> 注意：yii的url美化需要如下nginx配置的支持，否则即使你开了yii的url美化也没用。
```
#remove the index.php in url
location / {
    # Redirect everything that isn't a real file to index.php
    try_files \$uri \$uri/ /index.php\$is_args\$args;
}
```

如果您使用的是apache而不是nginx，那就需要在`web`目录下创建一个`.htaccess`文件：
```xml
<IfModule mod_rewrite.c>
    RewriteEngine on
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L]
</IfModule>
```


URL美化后的效果：
![Url美化后的YII欢迎界面](/images/20211109181803.png)
M0,
];

foreach($html as $name => $item){
    switch ($name) {
        case strpos($name, "example") !== false:
            echo Example::widget($item);
            break;
        case strpos($name, "markdown") !== false:
            echo Markdown::widget(["content" => $item]);
            break;
        default:
            break;
    }
}